#pragma once
#include <windows.h>
#include <winioctl.h>

typedef struct tagUNICODE_STRING
{
    USHORT Length;
    USHORT MaximumLength;
    PWSTR  Buffer; 
} UNICODE_STRING, *PUNICODE_STRING;


typedef enum _SYSTEM_INFORMATION_CLASS {  
    SystemBasicInformation,  //0
    SystemProcessorInformation,  //1
    SystemPerformanceInformation, //2 
    SystemTimeOfDayInformation,//3  
    SystemPathInformation,  //4
    SystemProcessInformation, //5  
    SystemCallCountInformation,  //6
    SystemDeviceInformation,  //7
    SystemProcessorPerformanceInformation,  //8
    SystemFlagsInformation,  //9
    SystemCallTimeInformation,  //10
    SystemModuleInformation,  //11
    SystemLocksInformation,  //12
    SystemStackTraceInformation,  //13
    SystemPagedPoolInformation,  //14
    SystemNonPagedPoolInformation,//15  
    SystemHandleInformation,  //16
    SystemObjectInformation,  //17
    SystemPageFileInformation,  //18
    SystemVdmInstemulInformation, //19 
    SystemVdmBopInformation,  //20
    SystemFileCacheInformation,  //21
    SystemPoolTagInformation,  //22
    SystemInterruptInformation,  //23
    SystemDpcBehaviorInformation,  //24
    SystemFullMemoryInformation,  //25
    SystemLoadGdiDriverInformation,  //26
    SystemUnloadGdiDriverInformation,  //27
    SystemTimeAdjustmentInformation,  //28
    SystemSummaryMemoryInformation,  //29
    SystemNextEventIdInformation,  //30
    SystemEventIdsInformation,  //31
    SystemCrashDumpInformation,  //32
    SystemExceptionInformation,  //33
    SystemCrashDumpStateInformation,  //34
    SystemKernelDebuggerInformation,  //35
    SystemContextSwitchInformation,  //36
    SystemRegistryQuotaInformation,  //37
    SystemExtendServiceTableInformation,//38  
    SystemPrioritySeperation,  //39
    SystemPlugPlayBusInformation,//40  
    SystemDockInformation,  //41
    SystemPowerInformation2,  //42
    SystemProcessorSpeedInformation,  //43
    SystemCurrentTimeZoneInformation,//44  
    SystemLookasideInformation,//45
	SystemSetTimeSlipEvent,                // 46 N Y
    SystemCreateSession,                // 47 N Y
    SystemDeleteSession,                // 48 N Y
    SystemInvalidInfoClass4,            // 49
    SystemRangeStartInformation,        // 50 Y N
    SystemVerifierInformation,            // 51 Y Y
    SystemAddVerifier,                    // 52 N Y
    SystemSessionProcessesInformation    // 53 Y N
} SYSTEM_INFORMATION_CLASS, *PSYSTEM_INFORMATION_CLASS; 

typedef enum _OBJECT_INFORMATION_CLASS {
    ObjectBasicInformation,
    ObjectNameInformation,
    ObjectTypeInformation,
    ObjectTypesInformation,
    ObjectHandleFlagInformation,
    ObjectSessionInformation,
    MaxObjectInfoClass  // MaxObjectInfoClass should always be the last enum
} OBJECT_INFORMATION_CLASS;

typedef struct _SYSTEM_HANDLE_TABLE_ENTRY_INFO {
    USHORT UniqueProcessId;
    USHORT CreatorBackTraceIndex;
    UCHAR ObjectTypeIndex;
    UCHAR HandleAttributes;
    USHORT HandleValue;
    PVOID Object;
    ULONG GrantedAccess;
} SYSTEM_HANDLE_TABLE_ENTRY_INFO, *PSYSTEM_HANDLE_TABLE_ENTRY_INFO;

typedef struct _SYSTEM_HANDLE_INFORMATION {
    ULONG NumberOfHandles;
    SYSTEM_HANDLE_TABLE_ENTRY_INFO Handles[ 1 ];
} SYSTEM_HANDLE_INFORMATION, *PSYSTEM_HANDLE_INFORMATION;

typedef struct _OBJECT_BASIC_INFORMATION {
    ULONG Attributes;
    ACCESS_MASK GrantedAccess;
    ULONG HandleCount;
    ULONG PointerCount;
    ULONG PagedPoolCharge;
    ULONG NonPagedPoolCharge;
    ULONG Reserved[ 3 ];
    ULONG NameInfoSize;
    ULONG TypeInfoSize;
    ULONG SecurityDescriptorSize;
    LARGE_INTEGER CreationTime;
} OBJECT_BASIC_INFORMATION, *POBJECT_BASIC_INFORMATION;

typedef struct _OBJECT_NAME_INFORMATION {               // ntddk wdm nthal
    UNICODE_STRING Name;                                // ntddk wdm nthal
} OBJECT_NAME_INFORMATION, *POBJECT_NAME_INFORMATION;   // ntddk wdm nthal

typedef struct _OBJECT_TYPE_INFORMATION {
    UNICODE_STRING TypeName;
    ULONG TotalNumberOfObjects;
    ULONG TotalNumberOfHandles;
    ULONG TotalPagedPoolUsage;
    ULONG TotalNonPagedPoolUsage;
    ULONG TotalNamePoolUsage;
    ULONG TotalHandleTableUsage;
    ULONG HighWaterNumberOfObjects;
    ULONG HighWaterNumberOfHandles;
    ULONG HighWaterPagedPoolUsage;
    ULONG HighWaterNonPagedPoolUsage;
    ULONG HighWaterNamePoolUsage;
    ULONG HighWaterHandleTableUsage;
    ULONG InvalidAttributes;
    GENERIC_MAPPING GenericMapping;
    ULONG ValidAccessMask;
    BOOLEAN SecurityRequired;
    BOOLEAN MaintainHandleCount;
    ULONG PoolType;
    ULONG DefaultPagedPoolCharge;
    ULONG DefaultNonPagedPoolCharge;
} OBJECT_TYPE_INFORMATION, *POBJECT_TYPE_INFORMATION;

typedef struct _OBJECT_ATTRIBUTES {
  ULONG           Length;
  HANDLE          RootDirectory;
  PUNICODE_STRING ObjectName;
  ULONG           Attributes;
  PVOID           SecurityDescriptor;
  PVOID           SecurityQualityOfService;
}  OBJECT_ATTRIBUTES, *POBJECT_ATTRIBUTES;

typedef struct _CLIENT_ID {
    HANDLE UniqueProcess;
    HANDLE UniqueThread;
} CLIENT_ID,*PCLIENT_ID;

#define OBJ_KERNEL_HANDLE       0x00000200L

#define InitializeObjectAttributes( p, n, a, r, s ) { \
    (p)->Length = sizeof( OBJECT_ATTRIBUTES );          \
    (p)->RootDirectory = r;                             \
    (p)->Attributes = a;                                \
    (p)->ObjectName = n;                                \
    (p)->SecurityDescriptor = s;                        \
    (p)->SecurityQualityOfService = NULL;               \
    }

typedef NTSTATUS (NTAPI *PnfZwOpenProcess)(
  _Out_     PHANDLE ProcessHandle,
  _In_      ACCESS_MASK DesiredAccess,
  _In_      POBJECT_ATTRIBUTES ObjectAttributes,
  _In_opt_  PCLIENT_ID ClientId
);

typedef NTSTATUS (NTAPI *PnfZwQuerySystemInformation)(   
    IN ULONG SystemInformationClass,   
    IN PVOID SystemInformation,   
    IN ULONG SystemInformationLength,   
    OUT PULONG ReturnLength);  

typedef NTSTATUS (NTAPI *PnfZwDuplicateObject)(
                 IN HANDLE                 SourceProcessHandle,
                 IN HANDLE                 SourceHandle,
                 IN HANDLE                 TargetProcessHandle,
                 OUT PHANDLE               TargetHandle,
                 IN ACCESS_MASK             DesiredAccess OPTIONAL,
                 IN BOOLEAN                 InheritHandle,
                 IN ULONG                   Options );

typedef NTSTATUS (NTAPI *PnfZwQueryObject)(
        IN HANDLE                ObjectHandle,
        IN ULONG                 ObjectInformationClass,
        OUT PVOID                ObjectInformation,
        IN ULONG                 ObjectInformationLength,
        OUT PULONG               ReturnLength OPTIONAL);

typedef NTSTATUS (NTAPI *PnfZwClose)(
  _In_  HANDLE Handle
);

template<> 
struct std::greater<PWeaponInfo>
{
    bool operator()(PWeaponInfo _X, PWeaponInfo _Y) const
    {
        return (_X->phyAttack > _Y->phyAttack);
    }
};

typedef enum tagWin32SysType{
 Windows32s,
 WindowsNT3,
 Windows95,
 Windows98,
 WindowsME,
 WindowsNT4,
 Windows2000,
 WindowsXP,
 WindowsVista,
 Windows7,
 Nothing
}Win32SysType;

#define RECOVER_INPUT_MESSAGE CTL_CODE(\
                     FILE_DEVICE_UNKNOWN, \
                     0x800, \
                     METHOD_BUFFERED, \
                     FILE_ANY_ACCESS)